﻿using BUGCOME.Infrastructure.Attribute;
using BUGCOME.Model.Auth;
using BUGCOME.Model.Common;
using BUGCOME.Model.Common.dto;
using BUGCOME.Service.Common.IServices;

namespace ZS.Service.System
{
    /// <summary>
    /// 字典类型服务实现类
    /// 继承基础服务类BaseService<DictType>，实现IDictTypeService接口
    /// 注：通过AppService特性标记服务类型为IDictTypeService，生命周期为 transient（瞬态）
    /// </summary>
    [AppService(ServiceType = typeof(IDictTypeService), ServiceLifetime = LifeTime.Transient)]
    public class DictTypeService : BaseService<DictType>, IDictTypeService
    {
        // 字典数据服务（用于操作字典数据相关业务）
        private readonly IDictDataService dictDataService;

        /// <summary>
        /// 构造函数（依赖注入字典数据服务）
        /// </summary>
        /// <param name="dictDataService">字典数据服务实例</param>
        public DictTypeService(IDictDataService dictDataService)
        {
            this.dictDataService = dictDataService;
        }

        /// <summary>
        /// 异步获取所有字典类型
        /// </summary>
        /// <returns>所有字典类型组成的列表</returns>
        public async Task<List<DictType>> GetAllAsync()
        {
            return await Queryable().ToListAsync();
        }

        /// <summary>
        /// 分页查询字典类型列表（异步）
        /// </summary>
        /// <param name="dict">查询条件（包含分页参数及筛选条件：字典名称、字典类型、状态、类型等）</param>
        /// <returns>分页结果（包含当前页数据及总条数等信息）</returns>
        public async Task<PagedInfo<DictType>> SelectDictTypeListAsync(DictTypeQueryDto dict)
        {
            // 构建查询表达式（动态拼接筛选条件）
            var exp = Expressionable.Create<DictType>();

            // 按字典名称模糊查询
            exp.AndIF(!string.IsNullOrEmpty(dict.DictName), it => it.DictName.Contains(dict.DictName));

            // 按字典类型模糊查询（对应DTO的DictType属性）
            exp.AndIF(!string.IsNullOrEmpty(dict.DictType), it => it.DType.Contains(dict.DictType));

            // 按状态精确匹配
            exp.AndIF(!string.IsNullOrEmpty(dict.Status), it => it.Status == dict.Status);

            // 按类型（系统内置标识）精确匹配
            exp.AndIF(!string.IsNullOrEmpty(dict.Type), it => it.Type.Equals(dict.Type));

            // 按创建日期范围筛选（开始时间，包含）
            exp.AndIF(dict.CreateTimeStart.HasValue, it => it.CreateTime >= dict.CreateTimeStart.Value);

            // 按创建日期范围筛选（结束时间，包含）
            exp.AndIF(dict.CreateTimeEnd.HasValue, it => it.CreateTime <= dict.CreateTimeEnd.Value);

            // 执行分页查询（按更新时间倒序，分页参数从dict中获取，因DictTypeDto继承自PagerInfo）
            return await GetPagesAsync(exp.ToExpression(), dict, f => f.UpdateTime,OrderByType.Desc
            );
        }

        /// <summary>
        /// 异步校验字典类型是否唯一（通过字典类型编码DType判断）
        /// </summary>
        /// <param name="dictType">待校验的字典类型实体</param>
        /// <returns>唯一标识：UNIQUE（唯一）/NOT_UNIQUE（不唯一）</returns>
        public async Task<string> CheckDictTypeUniqueAsync(DictType dictType)
        {
            // 查询数据库中是否存在相同DType的字典类型
            DictType existingDictType = await GetFirstAsync(f => f.DType == dictType.DType);
            // 逻辑说明：若存在相同DType的记录，且该记录ID与当前实体ID不同（排除自身），则判定为不唯一
            // 注：原代码存在笔误（dictType.Id != dictType.Id），应修正为existingDictType != null && existingDictType.Id != dictType.Id
            if (existingDictType != null && existingDictType.Id != dictType.Id)
            {
                return UserConstants.NOT_UNIQUE;
            }
            return UserConstants.UNIQUE;
        }

        /// <summary>
        /// 异步批量删除字典类型
        /// </summary>
        /// <param name="dictIds">待删除的字典类型ID数组</param>
        /// <returns>实际删除的数量</returns>
        /// <exception cref="CustomException">删除校验不通过时抛出（如包含系统内置类型、已关联字典数据）</exception>
        public async Task<int> DeleteDictTypeByIdsAsync(long[] dictIds)
        {
            // 校验：系统内置字典类型（Type=Y）不允许删除
            int sysCount = await CountAsync(s => s.Type == "Y" && dictIds.Contains(s.Id));
            if (sysCount > 0)
            {
                throw new CustomException($"删除失败：系统内置参数不能删除！");
            }

            // 校验：已分配字典数据的类型不允许删除
            foreach (var id in dictIds)
            {
                DictType dictType = await GetFirstAsync(x => x.Id == id);
                // 查询该类型下是否关联字典数据
                //if (await dictDataService.CountAsync(f => f.DictType == dictType.DType) > 0)
                //{
                //    throw new CustomException($"{dictType.DictName}已分配字典数据，不能删除");
                //}
                await dictDataService.Deleteable().Where(u => u.DictType == dictType.DType).ExecuteCommandAsync();
            }

            // 执行批量删除
            int count = await Context.Deleteable<DictType>().In(dictIds).ExecuteCommandAsync();
            return count;
        }

        /// <summary>
        /// 异步插入字典类型
        /// </summary>
        /// <param name="dictType">待插入的字典类型实体</param>
        /// <returns>插入后生成的主键ID</returns>
        public async Task<long> InsertDictTypeAsync(DictType dictType)
        {
            return await InsertReturnBigIdentityAsync(dictType);
        }

        /// <summary>
        /// 异步修改字典类型
        /// </summary>
        /// <param name="dictType">待修改的字典类型实体</param>
        /// <returns>修改操作影响的行数</returns>
        public async Task<int> UpdateDictTypeAsync(DictType dictType)
        {
            // 获取原字典类型信息
            DictType oldDict = await GetFirstAsync(x => x.Id == dictType.Id);
            // 若字典类型编码（DType）变更，同步更新关联的字典数据
            if (dictType.DType != oldDict.DType)
            {
                await dictDataService.UpdateDictDataTypeAsync(oldDict.DType, dictType.DType);
            }

            // 执行更新（忽略创建人字段，避免修改）
            return await Context.Updateable(dictType)
                .IgnoreColumns(it => new { dictType.CreateBy })
                .ExecuteCommandAsync();
        }

        /// <summary>
        /// 异步获取字典类型详情
        /// </summary>
        /// <param name="id">字典类型ID</param>
        /// <returns>对应的字典类型实体（不存在则为null）</returns>
        public async Task<DictType> GetInfoAsync(long id)
        {
            return await GetFirstAsync(f => f.Id == id);
        }

        /// <summary>
        /// 按字典类型通过自定义SQL查询字典数据
        /// </summary>
        /// <param name="dictType">字典类型编码（DType）</param>
        /// <returns>查询到的字典数据集合（不符合条件时返回null）</returns>
        public async Task<List<DictData>> SelectDictDataByCustomSqlAsync(string dictType)
        {
            // 获取该字典类型的详细信息（包含自定义SQL）
            var dictInfo = Queryable()
               .Where(f => f.DType == dictType).First();
            // 校验：字典类型不存在/无自定义SQL/自定义SQL非SELECT语句时，返回null
            if (dictInfo == null || dictInfo.CustomSql == null || !dictInfo.CustomSql.StartsWith("select", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }
            // 调用字典数据服务执行自定义SQL查询
            return await dictDataService.SelectDictDataByCustomSqlAsync(dictInfo);
        }
    }
}